package com.godyao.service.impl;

import cn.hutool.core.date.DateUtil;
import com.godyao.entity.IdMap;
import com.godyao.entity.UrlMap;
//import com.godyao.entity.UrlMapInfoTest;
//import com.godyao.repository.UrlMapInfoRepository;
//import com.godyao.repository.UrlMapInfoRepository2;
import com.godyao.repository.IdMapRepository;
import com.godyao.repository.UrlMapRepository;
import com.godyao.request.CommonRequest;
import com.godyao.service.ShortUrlService;
import com.godyao.utils.Base62Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.Optional;

/**
 * @author godyao
 * @date 2022/3/5
 */
@Primary
@CacheConfig(cacheNames = {"myCache"})
@Service
public class ShortUrlShardingServiceImpl implements ShortUrlService {
    private static final int DEFAULT_EXPIRE_DAYS = 3;

    private static final String DEFAULT_DIRECT_URL = "http://www.baidu.com";

    private static final String DOMAIN = "http://micro/";

    @Autowired
    private UrlMapRepository urlMapRepository;

    @Autowired
    private IdMapRepository idMapRepository;

    @Override
    @Caching(put = {
            @CachePut(key = "#urlMap.id"),
            @CachePut(key = "#urlMap.longUrl")
    })
    //@CachePut(key = "#urlMap.id")
    public String shorten(UrlMap urlMap) throws Exception {
        Date expireTime = urlMap.getExpireTime();
        if (null == expireTime) {
            expireTime = DateUtil.offsetDay(DateUtil.date(), DEFAULT_EXPIRE_DAYS);
            urlMap.setExpireTime(expireTime);
        }
        try{
            urlMapRepository.save(urlMap);
        }catch (Exception e) {
            e.printStackTrace();
            throw new Exception("longUrl重复");
        }
        if (null != urlMap.getId()) {
            return DOMAIN + Base62Util.encode(urlMap.getId());
        }
        throw new Exception("longUrl重复");
    }

    @Override
    @Cacheable(key = "#urlMap.longUrl")
    public String findShortByLong(UrlMap urlMap) {
        final Long idByLongUrl = urlMapRepository.findIdByLongUrl(urlMap.getLongUrl());
        return DOMAIN + Base62Util.encode(idByLongUrl);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void customerUrl(CommonRequest commonRequest) {
        Date expireTime = commonRequest.getExpireTime();
        if (null == expireTime) {
            expireTime = DateUtil.offsetDay(DateUtil.date(), DEFAULT_EXPIRE_DAYS);
        }
        final String shortUrl = commonRequest.getShortUrl();
        final long id = Base62Util.decode(shortUrl);
        final UrlMap save = urlMapRepository.save(UrlMap.builder().id(id).longUrl(commonRequest.getLongUrl()).expireTime(expireTime).build());
        final IdMap idMap = IdMap.builder().urlId(save.getId()).customerId(id).build();
        idMapRepository.save(idMap);
    }

    @Override
    @Cacheable(key = "#urlMap.id")
    public String redirect(UrlMap urlMap) {
        final IdMap idMap = idMapRepository.findByCustomerId(urlMap.getId()).orElse(new IdMap());
        if (null != idMap.getUrlId()) {
            return Optional.ofNullable(urlMapRepository.findActiveLongUrlByShortUrl(idMap.getUrlId())).orElse(DEFAULT_DIRECT_URL);
        }
        return Optional.ofNullable(urlMapRepository.findActiveLongUrlByShortUrl(urlMap.getId())).orElse(DEFAULT_DIRECT_URL);
    }
}
